home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_068 / mg1b / symbol.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  16KB  |  507 lines

  1. /*
  2.  * Symbol tables, and keymap setup.
  3.  * The terminal specific parts of building the
  4.  * keymap has been moved to a better place.
  5.  */
  6. #include    "def.h"
  7.  
  8. #ifdef    HASH
  9. Since you're seeing this, you must have defined HASH to try and get the
  10. hashing code back. You're getting an error because I (mwm@ucbvax) want you
  11. to read this.
  12.  
  13. With the change in function completion, there is at least one linear search
  14. through the function list for every hash lookup (ignoring the startup code).
  15. Given that there are probably actually MANY more linear searches for
  16. completion than fullname lookups, some structure other than a hash table is
  17. better suited to this purpose. I suggest trying sorting the lists for more
  18. speed, then going to a binary search tree, and finally going to a trie.
  19. #endif    HASH
  20.  
  21. /*
  22.  * Defined here so to collect the #ifdef MEYN config stuff in one file
  23.  * If you set either MINDENT or MFILL, then you need to change the bindings
  24.  * in this file to match: KCTRL|'M' -> newline-and-indent and KCTRL|'J' ->
  25.  * insert-newline for MINDENT, and ' ' -> insert-with-wrap for MFILL.
  26.  * MEYN is used for compile-time customization of the system for micros.
  27.  */
  28. #ifndef    MEYN
  29. int    mode = 0;            /* All modes off        */
  30. #else
  31. int    mode = MBSMAP|MINDENT;
  32. #endif
  33.  
  34. /*
  35.  * Defined by "main.c".
  36.  */
  37. extern    int    ctrlg();        /* Abort out of things        */
  38. extern    int    quit();            /* Quit                */
  39. extern    int    ctlxlp();        /* Begin macro            */
  40. extern    int    ctlxrp();        /* End macro            */
  41. extern    int    ctlxe();        /* Execute macro        */
  42. extern  int    showversion();        /* Show version numbers, etc.    */
  43.  
  44. /*
  45.  * Defined by "search.c".
  46.  */
  47. extern    int    forwsearch();        /* Search forward        */
  48. extern    int    backsearch();        /* Search backwards        */
  49. extern  int    searchagain();        /* Repeat last search command    */
  50. extern  int    forwisearch();        /* Incremental search forward    */
  51. extern  int    backisearch();        /* Incremental search backwards    */
  52. extern  int    queryrepl();        /* Query replace        */
  53.  
  54. /*
  55.  * Defined by "basic.c".
  56.  */
  57. extern    int    gotobol();        /* Move to start of line    */
  58. extern    int    backchar();        /* Move backward by characters    */
  59. extern    int    gotoeol();        /* Move to end of line        */
  60. extern    int    forwchar();        /* Move forward by characters    */
  61. extern    int    gotobob();        /* Move to start of buffer    */
  62. extern    int    gotoeob();        /* Move to end of buffer    */
  63. extern    int    forwline();        /* Move forward by lines    */
  64. extern    int    backline();        /* Move backward by lines    */
  65. extern    int    forwpage();        /* Move forward by pages    */
  66. extern    int    backpage();        /* Move backward by pages    */
  67. extern    int    pagenext();        /* Page forward next window    */
  68. extern    int    setmark();        /* Set mark            */
  69. extern    int    swapmark();        /* Swap "." and mark        */
  70. extern    int    gotoline();        /* Go to a specified line.    */
  71.  
  72. /*
  73.  * Defined by "buffer.c".
  74.  */
  75. extern    int    listbuffers();        /* Display list of buffers    */
  76. extern    int    usebuffer();        /* Switch a window to a buffer    */
  77. extern    int    poptobuffer();        /* Other window to a buffer    */
  78. extern    int    killbuffer();        /* Make a buffer go away.    */
  79. extern    int    savebuffers();        /* Save unmodified buffers    */
  80. extern    int    bufferinsert();        /* Insert buffer into another    */
  81. extern    int    notmodified();        /* Reset modification flag    */
  82.  
  83. #ifdef    DIRLIST
  84. /*
  85.  * Defined by "dirlist.c".
  86.  */
  87. extern    int    dirlist();        /* Directory list.        */
  88. #endif
  89.  
  90. /*
  91.  * Defined by "file.c".
  92.  */
  93. extern    int    filevisit();        /* Get a file, read write    */
  94. extern    int    poptofile();        /* Get a file, other window    */
  95. extern    int    filewrite();        /* Write a file            */
  96. extern    int    filesave();        /* Save current file        */
  97. extern    int    fileinsert();        /* Insert file into buffer    */
  98. #ifdef    BACKUP
  99. extern    int    makebkfile();        /* Control backups on saves    */
  100. #endif
  101.  
  102. /*
  103.  * Defined by "match.c"
  104.  */
  105. extern    int    blinkparen();        /* Fake blink-matching-paren var */
  106. extern    int    showmatch();        /* Hack to show matching paren     */
  107.  
  108. /*
  109.  * Defined by "random.c".
  110.  */
  111. extern    int    selfinsert();        /* Insert character        */
  112. extern    int    showcpos();        /* Show the cursor position    */
  113. extern    int    twiddle();        /* Twiddle characters        */
  114. extern    int    quote();        /* Insert literal        */
  115. extern    int    openline();        /* Open up a blank line        */
  116. extern    int    newline();        /* Insert CR-LF            */
  117. extern    int    deblank();        /* Delete blank lines        */
  118. extern    int    justone();        /* Delete extra whitespace    */
  119. extern    int    delwhite();        /* Delete all whitespace    */
  120. extern    int    indent();        /* Insert CR-LF, then indent    */
  121. extern    int    forwdel();        /* Forward delete        */
  122. extern    int    backdel();        /* Backward delete in        */
  123. extern    int    killline();        /* Kill forward            */
  124. extern    int    yank();            /* Yank back from killbuffer.    */
  125. extern    int    bsmapmode();        /* set bsmap mode        */
  126. extern    int    flowmode();        /* set flow mode        */
  127. extern    int    indentmode();        /* set auto-indent mode        */
  128. extern    int    fillmode();        /* set word-wrap mode        */
  129.  
  130. /*
  131.  * Defined by "region.c".
  132.  */
  133. extern    int    killregion();        /* Kill region.            */
  134. extern    int    copyregion();        /* Copy region to kill buffer.    */
  135. extern    int    lowerregion();        /* Lower case region.        */
  136. extern    int    upperregion();        /* Upper case region.        */
  137. #ifdef    PREFIXREGION
  138. extern    int    prefixregion();        /* Prefix all lines in region    */
  139. extern    int    setprefix();        /* Set line prefix string    */
  140. #endif
  141.  
  142. /*
  143.  * Defined by "spawn.c".
  144.  */
  145. extern    int    spawncli();        /* Run CLI in a subjob.        */
  146. #ifdef    VMS
  147. extern    int    attachtoparent();    /* Attach to parent process    */
  148. #endif
  149.  
  150. /*
  151.  * Defined by "window.c".
  152.  */
  153. extern    int    reposition();        /* Reposition window        */
  154. extern    int    refresh();        /* Refresh the screen        */
  155. extern    int    nextwind();        /* Move to the next window    */
  156. extern  int    prevwind();        /* Move to the previous window    */
  157. extern    int    onlywind();        /* Make current window only one    */
  158. extern    int    splitwind();        /* Split current window        */
  159. extern    int    delwind();        /* Delete current window    */
  160. extern    int    enlargewind();        /* Enlarge display window.    */
  161. extern    int    shrinkwind();        /* Shrink window.        */
  162.  
  163. /*
  164.  * Defined by "word.c".
  165.  */
  166. extern    int    backword();        /* Backup by words        */
  167. extern    int    forwword();        /* Advance by words        */
  168. extern    int    upperword();        /* Upper case word.        */
  169. extern    int    lowerword();        /* Lower case word.        */
  170. extern    int    capword();        /* Initial capitalize word.    */
  171. extern    int    delfword();        /* Delete forward word.        */
  172. extern    int    delbword();        /* Delete backward word.    */
  173.  
  174. /*
  175.  * Defined by "extend.c".
  176.  */
  177. extern    int    extend();        /* Extended commands.        */
  178. extern    int    desckey();        /* Help key.            */
  179. extern    int    bindtokey();        /* Modify key bindings.        */
  180. extern    int    unsetkey();        /* Unbind a key.        */
  181. extern    int    wallchart();        /* Make wall chart.        */
  182. #ifdef    STARTUP
  183. extern    int    evalexpr();        /* Extended commands (again)    */
  184. extern    int    evalbuffer();        /* Evaluate current buffer    */
  185. extern    int    evalfile();        /* Evaluate a file        */
  186. #endif
  187.  
  188. /*
  189.  * defined by "paragraph.c" - the paragraph justification code.
  190.  */
  191. extern    int    gotobop();        /* Move to start of paragraph.    */
  192. extern    int    gotoeop();        /* Move to end of paragraph.    */
  193. extern    int    fillpara();        /* Justify a paragraph.        */
  194. extern    int    killpara();        /* Delete a paragraph.        */
  195. extern    int    setfillcol();        /* Set fill column for justify.    */
  196. extern    int    fillword();        /* Insert char with word wrap.    */
  197.  
  198. /*
  199.  * defined by prefix.c
  200.  */
  201. extern    int    help();            /* Parse help key.        */
  202. extern    int    ctlx4hack();        /* Parse a pop-to key.        */
  203.  
  204. typedef    struct    {
  205.     KEY    k_key;            /* Key to bind.            */
  206.     int    (*k_funcp)();        /* Function.            */
  207.     char    *k_name;        /* Function name string.    */
  208. }    KEYTAB;
  209.  
  210. /*
  211.  * Default key binding table. This contains
  212.  * the function names, the symbol table name, and (possibly)
  213.  * a key binding for the builtin functions. There are no
  214.  * bindings for C-U or C-X. These are done with special
  215.  * code, but should be done normally.
  216.  */
  217. KEYTAB    key[] = {
  218. #ifdef    MEYN        /* Add meyer's peculiar bindings */
  219.     KCTRL|'J',    newline,    "insert-newline",
  220.     KCTRL|'M',    indent,        "newline-and-indent",
  221.     KCTLX|'N',    nextwind,     "next-window",
  222.     KCTLX|'P',    prevwind,    "previous-window",
  223.     KMETA|KCTRL|'C',quit,        "save-buffers-kill-emacs",
  224.     KMETA|KCTRL|'L',refresh,    "redraw-display",
  225.     KMETA|'G',    gotoline,    "goto-line",
  226.     KMETA|'J',    fillpara,    "fill-paragraph",
  227.     KMETA|'Q',    queryrepl,    "query-replace",
  228. #endif
  229.     KCTRL|'@',    setmark,    "set-mark-command",
  230.     KCTRL|'A',    gotobol,    "beginning-of-line",
  231.     KCTRL|'B',    backchar,    "backward-char",
  232.     KCTRL|'D',    forwdel,    "delete-char",
  233.     KCTRL|'E',    gotoeol,    "end-of-line",
  234.     KCTRL|'F',    forwchar,    "forward-char",
  235.     KCTRL|'G',    ctrlg,        "keyboard-quit",
  236.     KCTRL|'H',    help,        "help",
  237.     KCTRL|'I',    selfinsert,    "self-insert-command",
  238. #ifndef    MEYN
  239.     KCTRL|'J',    indent,        "newline-and-indent",
  240. #endif
  241.     KCTRL|'L',    reposition,    "recenter",
  242.     KCTRL|'K',    killline,    "kill-line",
  243. #ifndef    MEYN
  244.     KCTRL|'M',    newline,    "insert-newline",
  245. #endif
  246.     KCTRL|'N',    forwline,    "next-line",
  247.     KCTRL|'O',    openline,    "open-line",
  248.     KCTRL|'P',    backline,    "previous-line",
  249.     KCTRL|'Q',    quote,        "quoted-insert",
  250.     KCTRL|'R',    backisearch,    "isearch-backward",
  251.     KCTRL|'S',    forwisearch,    "isearch-forward",
  252.     KCTRL|'T',    twiddle,    "transpose-chars",
  253.     KCTRL|'V',    forwpage,    "scroll-up",
  254.     KCTRL|'W',    killregion,    "kill-region",
  255.     KCTRL|'Y',    yank,        "yank",
  256. #ifdef    VMS
  257.     KCTRL|'Z',    attachtoparent,    "suspend-emacs",
  258. #else
  259.     KCTRL|'Z',    spawncli,    "suspend-emacs",
  260. #endif
  261.     KCTLX|KCTRL|'B',listbuffers,    "list-buffers",
  262. #ifndef    MEYN
  263.     KCTLX|KCTRL|'C',quit,        "save-buffers-kill-emacs",
  264. #endif
  265. #ifdef    DIRLIST
  266.     KCTLX|KCTRL|'D',dirlist,    "display-directory",
  267. #endif
  268.     KCTLX|KCTRL|'F',filevisit,    "find-file",
  269.     KCTLX|KCTRL|'L',lowerregion,    "downcase-region",
  270.     KCTLX|KCTRL|'O',deblank,    "delete-blank-lines",
  271.     KCTLX|KCTRL|'S',filesave,    "save-buffer",
  272.     KCTLX|KCTRL|'U',upperregion,    "upcase-region",
  273.     KCTLX|KCTRL|'W',filewrite,    "write-file",
  274.     KCTLX|KCTRL|'X',swapmark,    "exchange-point-and-mark",
  275.     KCTLX|'=',    showcpos,    "what-cursor-position",
  276.     KCTLX|'(',    ctlxlp,        "start-kbd-macro",
  277.     KCTLX|')',    ctlxrp,        "end-kbd-macro",
  278.     KCTLX|'^',    enlargewind,    "enlarge-window",
  279.     KCTLX|'0',    delwind,    "delete-window",
  280.     KCTLX|'1',    onlywind,    "delete-other-windows",
  281.     KCTLX|'2',    splitwind,    "split-window-vertically",
  282.     KCTLX|'4',    ctlx4hack,    "ctrlx-four-hack",
  283.     KCTLX|'B',    usebuffer,    "switch-to-buffer",
  284.     KCTLX|'E',    ctlxe,        "call-last-kbd-macro",
  285.     KCTLX|'F',    setfillcol,    "set-fill-column",
  286.     KCTLX|'I',    fileinsert,    "insert-file",
  287.     KCTLX|'K',    killbuffer,    "kill-buffer",
  288.     KCTLX|'S',    savebuffers,    "save-some-buffers",
  289. #ifndef    MEYN
  290.     KCTLX|'O',    nextwind,    "next-window",
  291.     KMETA|'%',    queryrepl,    "query-replace",
  292. #endif
  293.     KMETA|KCTRL|'V',pagenext,    "scroll-other-window",
  294.     KMETA|'>',    gotoeob,    "end-of-buffer",
  295.     KMETA|'<',    gotobob,    "beginning-of-buffer",
  296.     KMETA|'[',    gotobop,    "backward-paragraph",
  297.     KMETA|'\\',    delwhite,    "delete-horizontal-space",
  298.     KMETA|']',    gotoeop,    "forward-paragraph",
  299.     KMETA|' ',    justone,    "just-one-space",
  300.     KMETA|'B',    backword,    "backward-word",
  301.     KMETA|'C',    capword,    "capitalize-word",
  302.     KMETA|'D',    delfword,    "kill-word",
  303.     KMETA|'F',    forwword,    "forward-word",
  304.     KMETA|'L',    lowerword,    "downcase-word",
  305. #ifndef    MEYN
  306.     KMETA|'Q',    fillpara,    "fill-paragraph",
  307. #endif
  308.     KMETA|'R',    backsearch,    "search-backward",
  309.     KMETA|'S',    forwsearch,    "search-forward",
  310.     KMETA|'U',    upperword,    "upcase-word",
  311.     KMETA|'V',    backpage,    "scroll-down",
  312.     KMETA|'W',    copyregion,    "copy-region-as-kill",
  313.     KMETA|'X',    extend,        "execute-extended-command",
  314.     KMETA|'~',    notmodified,    "not-modified",
  315. #ifndef    MEYN
  316.     -1,        prevwind,    "previous-window",
  317.     -1,        refresh,    "redraw-display",
  318.     -1,        gotoline,    "goto-line",
  319. #endif
  320. #ifdef    STARTUP
  321.     -1,        evalexpr,    "eval-expression",
  322.     -1,        evalbuffer,    "eval-current-buffer",
  323.     -1,        evalfile,    "load",
  324. #endif
  325.     -1,        bsmapmode,    "bsmap-mode",
  326.     -1,        flowmode,    "flow-mode",
  327.     -1,        indentmode,    "auto-indent-mode",
  328.     -1,        fillmode,    "auto-fill-mode",
  329.     -1,        fillword,    "insert-with-wrap",
  330.     -1,        shrinkwind,    "shrink-window",
  331.     -1,        searchagain,    "search-again",
  332.     -1,        unsetkey,    "global-unset-key",
  333.     -1,        bindtokey,    "global-set-key",
  334.     -1,        killpara,    "kill-paragraph",
  335.     -1,        showversion,    "emacs-version",
  336.     -1,        blinkparen,    "blink-matching-paren",
  337.     -1,        showmatch,    "blink-matching-paren-hack",
  338.     -1,        bufferinsert,    "insert-buffer",
  339. #ifdef    VMS
  340.     -1,        spawncli,    "push-to-dcl",
  341. #endif
  342. #ifdef    PREFIXREGION
  343.     -1,        prefixregion,    "prefix-region",
  344.     -1,        setprefix,    "set-prefix-string",
  345. #endif
  346. #ifdef    BACKUP
  347.     -1,        makebkfile,    "make-backup-files",
  348. #endif
  349.     /* You can actually get to these with keystrokes. See prefix.c */
  350.     -1,        poptobuffer,    "switch-to-buffer-other-window",
  351.     -1,        poptofile,    "find-file-other-window",
  352.     -1,        desckey,    "describe-key-briefly",
  353.     -1,        wallchart,    "describe-bindings",
  354. };
  355.  
  356. #define    NKEY    (sizeof(key) / sizeof(key[0]))
  357.  
  358. /*
  359.  * Just some definitions, to keep ANSI compilers happy.
  360.  */
  361. VOID    keymapinit();
  362. VOID    keyadd();
  363. VOID    keydup();
  364.  
  365. /*
  366.  * Symbol table lookup.
  367.  * Return a pointer to the SYMBOL node, or NULL if
  368.  * the symbol is not found.
  369.  */
  370. SYMBOL    *
  371. symlookup(cp) register char *cp; {
  372.     register SYMBOL    *sp;
  373.  
  374. #ifdef    HASH
  375.     sp = symbol[symhash(cp)];
  376. #else
  377.     sp = symbol[0];
  378. #endif
  379.     while (sp != NULL) {
  380.         if (strcmp(cp, sp->s_name) == 0)
  381.             return (sp);
  382. #ifdef    HASH
  383.         if ((sp->s_flags&SFEND) != 0) break;
  384. #endif
  385.         sp = sp->s_symp;
  386.     }
  387.     return (NULL);
  388. }
  389.  
  390. #ifdef    HASH
  391. /*
  392.  * Take a string, and compute the symbol table
  393.  * bucket number. This is done by adding all of the characters
  394.  * together, and taking the sum mod NSHASH. The string probably
  395.  * should not contain any GR characters; if it does the "*cp"
  396.  * may get a nagative number on some machines, and the "%"
  397.  * will return a negative number!
  398.  */
  399. symhash(cp) register char *cp; {
  400.     register int    c;
  401.     register int    n;
  402.  
  403.     n = 0;
  404.     while ((c = *cp++) != 0)
  405.         n += c;
  406.     return (n % NSHASH);
  407. }
  408. #endif
  409.  
  410. /*
  411.  * Build initial keymap. The funny keys
  412.  * (commands, odd control characters) are mapped using
  413.  * a big table and calls to "keyadd". The printing characters
  414.  * are done with some do-it-yourself handwaving. The terminal
  415.  * specific keymap initialization code is called at the
  416.  * very end to finish up. All errors are fatal.
  417.  */
  418. VOID
  419. keymapinit() {
  420.     register SYMBOL    *sp;
  421.     register KEYTAB    *kp;
  422.     register int    i;
  423.  
  424.     for (i=0; i<NKEYS; ++i)
  425.         binding[i] = NULL;
  426.     for (kp = &key[0]; kp < &key[NKEY]; ++kp)
  427.         keyadd(kp->k_key, kp->k_funcp, kp->k_name);
  428.     keydup((KEY) (KCTLX|KCTRL|'G'),    "keyboard-quit");
  429.     keydup((KEY) (KMETA|KCTRL|'G'),    "keyboard-quit");
  430.     keyadd((KEY) (KMETA|0x7F), delbword,
  431.                 "backward-kill-word");
  432.     keyadd((KEY) 0x7F, backdel,    "backward-delete-char");
  433.     /*
  434.      * add duplicates (GNU-stuff)
  435.      */
  436.     keydup((KEY) (KCTLX|KCTRL|'Z'), "suspend-emacs");
  437.     /*
  438.      * Should be bound by "tab" already.
  439.      */
  440.     if ((sp=symlookup("self-insert-command")) == NULL)
  441.         panic("no self-insert-command in keymapinit");
  442.     for (i=0x20; i<0x7F; ++i) {
  443.         if (binding[i] != NULL)
  444.             panic("nonull binding in keymapinit");
  445.         binding[i] = sp;
  446.     }
  447.     ttykeymapinit();
  448. #ifdef    HASH
  449.     /* Link up the symbol table entries    */
  450.     for (sp = symbol[i = 0]; i < NSHASH-1; sp = sp->s_symp)
  451.         if (sp->s_symp == NULL) sp->s_symp = symbol[++i];
  452. #endif            
  453. }
  454.  
  455. /*
  456.  * Create a new builtin function "name"
  457.  * with function "funcp". If the "new" is a real
  458.  * key, bind it as a side effect. All errors
  459.  * are fatal.
  460.  */
  461. VOID
  462. keyadd(new, funcp, name) register KEY new; int (*funcp)(); char *name; {
  463.     register SYMBOL    *sp;
  464. #ifdef    HASH
  465.     register int    hash;
  466. #endif
  467.  
  468.     if ((sp=(SYMBOL *)malloc(sizeof(SYMBOL))) == NULL)
  469.         panic("No memory");
  470. #ifdef    HASH
  471.     hash = symhash(name);
  472.     if (symbol[hash] == NULL) sp->s_flags |= SFEND;
  473.     sp->s_symp = symbol[hash];
  474.     symbol[hash] = sp;
  475. #else
  476.     sp->s_symp = symbol[0];
  477.         symbol[0] = sp;
  478. #endif
  479.     sp->s_name = name;
  480.     sp->s_funcp = funcp;
  481.     if (new >= 0) {                /* Bind this key.    */
  482.         if (binding[new] != NULL)
  483.             panic("rebinding old symbol");
  484.         binding[new] = sp;
  485.     }
  486. }
  487.  
  488. /*
  489.  * Bind key "new" to the existing
  490.  * routine "name". If the name cannot be found,
  491.  * or the key is already bound, abort.
  492.  */
  493. VOID
  494. keydup(new, name) register KEY new; char *name; {
  495.     register SYMBOL    *sp;
  496.  
  497.     if (binding[new]!=NULL || (sp=symlookup(name))==NULL) {
  498. #ifdef    KEYDUP_ERROR
  499.         fprintf (stderr, "keydup: binding[%d] = %x",
  500.                 new, binding[new]);
  501.         fprintf (stderr, " and symlookup(%s) == %x\n", name, sp);
  502. #endif
  503.         panic("keydup");
  504.     }
  505.     binding[new] = sp;
  506. }
  507.